﻿#Persistent
#NoTrayIcon
#SingleInstance, Force
; #Include <JSON>
DetectHiddenWindows On
SetTitleMatchMode 2
If (A_Args[1]="")
	ExitApp
Else
	SetTimer, scriptexit, 10000
global CloudInput:=SubStr(A_Args[2]?A_Args[2]:"BD",1,2) "CloudInput"
CopyOfData:="", ReceivePID:=0
OnMessage(10000, "ReceiveMsg")
Return

scriptexit:
	EmptyMem()
	Process, Exist, % A_Args[1]
	If !ErrorLevel
		ExitApp
Return
EmptyMem(PID="AHK Rocks"){
	pid:=(pid="AHK Rocks") ? DllCall("GetCurrentProcessId") : pid
	h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid)
	DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
	DllCall("CloseHandle", "Int", h)
}
ReceiveMsg(wParam, lParam){
	global ReceivePID, Texthwnd
	ReceivePID:=wParam, Texthwnd:=lParam
	SetTimer, CloudInput, -30
}

Send_WM_COPYDATA(ByRef StringToSend, ByRef TargetScriptTitle)  ; 在这种情况中使用 ByRef 能节约一些内存.
; 此函数发送指定的字符串到指定的窗口然后返回收到的回复.
; 如果目标窗口处理了消息则回复为 1, 而消息被忽略了则为 0.
{
    VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0)  ; 分配结构的内存区域.
    ; 首先设置结构的 cbData 成员为字符串的大小, 包括它的零终止符:
    SizeInBytes := (StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1)
    NumPut(SizeInBytes, CopyDataStruct, A_PtrSize)  ; 操作系统要求这个需要完成.
    NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize)  ; 设置 lpData 为到字符串自身的指针.
    ; 必须使用发送 SendMessage 而不是投递 PostMessage.
    SendMessage, 0x4a, % DllCall("GetCurrentProcessId"), &CopyDataStruct,, %TargetScriptTitle%  ; 0x4a 为 WM_COPYDAT
    return ErrorLevel  ; 返回 SendMessage 的回复给我们的调用者.
}
SendRequest(url, Method="GET", postData=""){ 
	WebRequest:=ComObjCreate("WinHttp.WinHttpRequest.5.1"), WebRequest.Open(Method, url, (Method="POST" ? 1 : 0))
	WebRequest.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
	WebRequest.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
	WebRequest.Send(postData), WebRequest.WaitForResponse(-1)
	Return WebRequest.ResponseText
}
JScript(Script:=""){
	static doc
	ComObjError(1)
	Try {
		doc:=ComObjCreate("htmlfile"), doc.write("<meta http-equiv='X-UA-Compatible' content='IE=9'><body><script>" Script "</script></body>")
		Return ObjBindMethod(doc.parentWindow, "eval")
	} Catch {
		sc:=ComObjCreate("ScriptControl"), sc.Language:="JScript", sc.ExecuteStatement(Script)
		Return ObjBindMethod(sc, "Eval")
	}
}
GGCloudInput(input){
	Script=
	(LTrim
		var gk=function(a){return function(){return a}},hk=function(a,b){for(var c=0;c<b.length-2;c+=3){var d=b.charAt(c+2),
		d="a"<=d?d.charCodeAt(0)-87:Number(d),d="+"==b.charAt(c+1)?a>>>d:a<<d;a="+"==b.charAt(c)?a+d&4294967295:a^d}return a},
		ik=null,jk=function(a){var b;if(null!==ik)b=ik;else{b=gk(String.fromCharCode(84));var c=gk(String.fromCharCode(75));b=[b(),b()];
		b[1]=c();b=(ik=window[b.join(c())]||"")||""}var d=gk(String.fromCharCode(116)),c=gk(String.fromCharCode(107)),d=[d(),d()];d[1]=c();
		c="&"+d.join("")+"=";d=b.split(".");b=Number(d[0])||0;for(var e=[],f=0,g=0;g<a.length;g++){var l=a.charCodeAt(g);
		128>l?e[f++]=l:(2048>l?e[f++]=l>>6|192:(55296==(l&64512)&&g+1<a.length&&56320==(a.charCodeAt(g+1)&64512)?(l=65536+((l&1023)<<10)+(a.charCodeAt(++g)&1023),
		e[f++]=l>>18|240,e[f++]=l>>12&63|128):e[f++]=l>>12|224,e[f++]=l>>6&63|128),e[f++]=l&63|128)}a=b;for(f=0;f<e.length;f++)a+=e[f],
		a=hk(a,"+-a^+6");a=hk(a,"+-3^+b+-f");a^=Number(d[1])||0;0>a&&(a=(a&2147483647)+2147483648);a`%=1E6;return c+(a.toString()+"."+(a^b))};
		ik='439034.2746551257';
	)
	js:=JScript(Script)
	ComObjError(0)
	KeyWord:=StrReplace(input, "'", "\'")
	url:="https://translate.google.cn/translate_a/single?client=webapp&sl=zh-CN&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&otf=0&ssel=0&tsel=0&pc=1&kc=1" js.("jk('" KeyWord "')")
	jsondata:=SendRequest(url, "POST", "q=" js.("encodeURIComponent('" KeyWord "')")), obj:=js.("(" jsondata ")")
	If InStr(obj[0][0][0],"'")
		Return 0
	Return input "`n" obj[0][0][0] "`n" input
}
BDCloudInput(input){
	static hObject
	If (!hObject){
		hObject:=ComObjCreate("WinHttp.WinHttpRequest.5.1")
		hObject.SetTimeouts(100, 100, 100, 100)
	}
	js:=JScript()
	hObject.Open("GET", "http://olime.baidu.com/py?input=" input "&inputtype=py&bg=0&ed=20&result=hanzi&resultcoding=utf-8&ch_en=0&clientinfo=web&version=1", 0)  
	Try {
		hObject.Send()
		obj:=js.("(" hObject.ResponseText ")"), obj:=obj["result"][0][0]
		If obj[0]
			Return obj[2]["pinyin"] "`n" obj[0] "`n" input
	}
	Return 0
}
CloudInput:
	If (Msg:=GetText(Texthwnd)){
		result:=%CloudInput%(Msg)
		If (result=0&&Msg:=GetText(Texthwnd))
			Method:=(CloudInput="BDCloudInput"?"GGCloudInput":"BDCloudInput"), result:=%Method%(Msg)
		If (Msg=GetText(Texthwnd))
			If (result){
				Send_WM_COPYDATA("<<CloudResult>>" result, "ahk_class AutoHotkey ahk_pid" ReceivePID)
			} Else
				SetTimer, CloudInput, -50
	}
Return

GetText(Hwnd){
	ControlGetText, Msg, , ahk_id%Hwnd%
	Return Msg
}